/*************************************************************************
 * Nuvoton Technology Corporation confidential
 *
 * Copyright (c) 2009 by Nuvoton Technology Corporation
 * All rights reserved
 * 
 * FILENAME
 *     Atapi.h
 *
 * VERSION
 *     1.0
 *
 * DESCRIPTION
 *     The header file for NUC900 ATAPI Interface Controller.
 *
 * HISTORY
 *     2008.06.25		Created
 *
 * REMARK
 *     None
 **************************************************************************/
#ifndef _ATAPI_H_
#define _ATAPI_H_

#ifdef ECOS
#include "wbio.h" 
#include "wbtypes.h"

#define sysprintf diag_printf
#define IRQ_ATAPI 22

#else
#include "wblib.h" 
#endif

#define SCATTER_GATHER 0

/* I/O routines */
#define ide_outp     outpw
#define ide_inp      inpw
#define ide_outphw   outpw
#define ide_inphw    inpw
// #define	ide_outphw(port,value) *((volatile USHORT *)(ATAPI_BASE_ADDRRESS+port))=value
// #define	ide_inphw(port)		   *((volatile USHORT *)(ATAPI_BASE_ADDRRESS+port))

#define IDENTIFY_DRV   0xEC
#define SET_MULTIPLE   0xC6
#define SET_FEATURE    0xEF
#define READ_SEC	   0x20
#define WRITE_SEC	   0x30
#define READ_MULTIPLE  0xC4
#define WRITE_MULTIPLE 0xC5
#define READ_DMA          0xC8
#define READ_DMA_EXT   0x25
#define WRITE_DMA        0xCA
#define WRITE_DMA_EXT  0x35
#define SET_FEATURES   0xEF                       
#define MASTER_MODE    0xA0	  // CHS addressing mode & selected Drive 0
#define SLAVE_MODE     0xB0	  // CHS addressing mode & selected Drive 1
#define LBA_MODE         0x40	  // LBA enable
//---------------------------- Structure----------------------------------
typedef struct 
{
    USHORT   temp1;
    USHORT   cylinders;
    USHORT   temp2;
    USHORT   heads;
    USHORT   temp3;
    USHORT   temp4;
    USHORT   sectors;
    USHORT   temp5[3];
    UCHAR    ser_no[20];
    USHORT   temp6;
    USHORT   temp7;
    USHORT   ecc_num;
    UCHAR    firware_rev[8];
    UCHAR    model_num[40];
    USHORT   support_max_sector_no;   /* word 47 */
    USHORT   temp8;                   /* word 48 */
    USHORT   capability;              /* word 49 */
    USHORT   reserved50;              /* word 50 */
    USHORT   pio_mode;                /* word 51 */
    USHORT   dma_mode;                /* word 52 */
    USHORT   field_valid;             /* word 53 */
    USHORT   cur_cylinders;           /* word 54 */
    USHORT   cur_heads;               /* word 55 */
    USHORT   cur_sectors;             /* word 56 */
    USHORT   temp9[2];                /* word 57 ~ 58 */
    USHORT   current_max_sector_no;   /* word 59 */    
    USHORT   lba_capacity[2];         /* word 60 ~ 61: Total number of user addressable sectors */
    USHORT   temp10[2];               /* word 62, 63 */
    USHORT   eide_pio_mode;           /* word 64 */              
    USHORT   temp11[15];              /* word 65 ~ 79 */
    USHORT   major_version;        // word 80
    USHORT   temp11_1[2];           // word 81, 82
    USHORT   command_set_support;     /* word 83 */
    USHORT   temp12[4];               /* word 84 ~ 87 */        
    USHORT   udma_modes;              /* word 88 */
    USHORT   temp13[11];              /* word 89 ~ 99 */    
    UINT32   max_lba_for_48bit[2];    /* word 100 ~ 103: Maximum user LBA for 48-bit Address feature set */        
    USHORT   temp14[152];             /* word 104 ~ 255 */    
} _hd_information;
//---------------------------- Variable----------------------------------
extern UINT32 volatile _atapi_DMACRWABORT;  // DMAC READ/WRITE Target Abort Interrupt Flag 
extern UINT32 volatile _atapi_ENDOFSECTOR;   // End of Sectors Transfer Interrupt Flag
extern UINT32 volatile _atapi_DMARQ;               // DMARQ Interrupt Flag
extern UINT32 volatile _atapi_INTRQ;                // INTRQ Interrupt Flag 
extern UCHAR gDMAtype;          
extern _hd_information IDE_HEADER_INFO[2]; 
extern UCHAR gScatterGather;
//------------------------- Function Prototype ---------------------------
//int atapiISR(void);
int atapiInitial(UCHAR engine_clock);
int atapiInitTransferMode(USHORT engine_clock);
int atapiReadHDInfo(USHORT drive_num);
int atapiSetFeature(UCHAR drive_no, USHORT transfer_type, USHORT mode);
int atapiSetMultiple(UCHAR drive_no, UCHAR uNumberOfSec);
int atapiReadSector(UCHAR drive_no, UINT32 start_sector, UCHAR sector_num, UCHAR *buf);
int atapiReadMultiple(UCHAR drive_no, UINT32 start_sector, UCHAR sector_num, UCHAR *buf);
int atapiWriteSector(UCHAR drive_no, UINT32 start_sector, UCHAR sector_num, UCHAR *buf);
int atapiWriteMultiple(UCHAR drive_no, UINT32 start_sector, UCHAR sector_num, UCHAR *buf);
int atapiReadDMA(UCHAR drive_no, UINT32 DMAstartaddr, UINT32 startLBA,  USHORT count);
int atapiWriteDMA(UCHAR drive_no, UINT32 DMAstartaddr, UINT32 startLBA,  USHORT count);
//----------------------------------------------------------------------
UINT32 atapiGetDriveCapacity(USHORT drive_no);
void atapiTransferLBAtoCHS(UCHAR drive_no, UINT32 startLBA, USHORT *_HD_HEAD, USHORT *_HD_CYLH, USHORT *_HD_CYLL, USHORT *_HD_SEC);
int atapiSetTransferTiming(USHORT type, USHORT mode, USHORT clock);
int atapiHWReset(INT device);

int atapi_wait_BSY(void);
int atapi_wait_DRQ(UCHAR n);
int atapi_wait_INTRQ(void);
int atapi_wait_ENDOFSECTOR(void);
int atapi_wait_DMATIP(void);

#endif /* End of _ATAPI_H_ */
